package calculatrice;
// ==========================================================================
//
//	- Terme -
//
// ==========================================================================
//	<Facteur>(<OpeMul><Facteur>)
// ==========================================================================

import java.util.regex.Matcher;
import java.util.regex.Pattern;
import netg.*;

/**
 * <b>La classe Terme </b>
 * <p>
 *	Terme = Facteur opeMul Facteur OU Facteur
 * </p>
 * @author BOAZIZ M , BOUAYADI R , DRAMSY C , OCCELLO A , SENG D
 * @version 1.0
 *
 * @see Facteur
 * @see OpeMul
 *
 */
public class Terme {
	/**
	 *	Le premier facteur de du terme
	 *  @see Terme#setFacteur(Facteur,int)
	  */
	private Facteur f1;
	/**
	 *	Le deuxieme facteur de du terme
	 *  @see Terme#setFacteur(Facteur,int)
	  */
	private Facteur f2;
	/**
	 * Verifie si le Terme est valide ou pas
	 * @see Terme#isActif()
	 */
	private boolean actif;
	/**
	 * L'operateur multiplication du terme
	 * @see Terme#setO(char)
	 * @see Terme#getO()
	 */
	private OpeMul O;

	//constructeur
	/**
	 * Constructeur de Terme
	 * <p>
	 * Il créer un Terme à partir d'un String S <br/>
	 * <u><b>si ce String a la forme d'un Terme :</b></u><br/>
	 * ex: 1 * 2(3+5)/8<br/>
	 * Il mettra actif à true et donc l'expression est valide<br/><br/>
	 * <u><b>si ce String n'a pas  la forme d'une expression :</b></u><br/>
	 * ex: 1++ ou bien a+b ou bien 1+2+(3*5)<br/>
	 *
	 * Il mettra actif à false et donc l'expression n'est pas valide valide<br/>
	 *
	 * </p>
	 * @param S
	 */
	public Terme(String S)
	{
		f1 = f2 = null;
		O = null;
		// =================
		//System.out.println("Terme "+S);
		//regex pour verifier s'il y a une operateur add ou pas
		String regex = "\\+|\\-";
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(S);
		char C[] = new char [S.length()];
		int i;

		//on remplit les tableaux par le caractre
		for(i = 0 ; i < S.length(); i++)
			C[i] = S.charAt(i);

		int couple = 0; //ce sera le couple de parenthses
		boolean find = false;
		int start = 0;int end;

		//pour verifier les priorites dominantes
		int prioAdd = 1000;
		int prioMul = 1000;

		for(i = 0 ; i < S.length() ; i++)
		{
			if(C[i] == '(') couple ++;
			if(C[i] == ')') couple --;
			else
			{
				if( ( OpeMul.isOpeMul(C[i]) ))
				{
					if(couple == 0)
					{
						start = i;
						find = true;
						setO(C[i]);
					}
					if(prioMul > couple)
						prioMul = couple;
				}
				if(OpeAdd.isOpeAdd(C[i]) && prioAdd > couple )
					prioAdd = couple;
			}
		}
		if( couple != 0 )
		{
			actif = false;
			return;
		}

		if(m.find() && prioMul >= prioAdd )
		{
			// Grer les priorits de dcoupage s'il y a un OpeAdd on le fait d'abbord .

			f1 = new Facteur(S);

			if(!f1.isActif())
			{
				actif = false;
				return;
			}
		}
		else if(find)
		{
			end = start+1;
			f1 = new Facteur(S.substring(0,start));
			f2 = new Facteur(S.substring(end ));
			if(!f1.isActif()||!f2.isActif())
			{
				actif = false;
				return;
			}
		}
		else
		{
			f1 = new Facteur(S);
			if(!f1.isActif())
			{
				actif = false;
				return;
			}
		}
		actif = true;
	}

	//mutateur
	/**
	 * Mutateur des deux facteur
	 * si indice = 1
	 * alors
	 * 	on modifie f1 par f
	 * sinon
	 * 	on modifier f2 par f
	 * @param f
	 * @param indice
	 */
	public void setFacteur( Facteur f , int indice )
	{
		if( indice == 1)
			f1 = f;
		else
			f2 = f;
	}
	/**
	 * Mutateur de l'OpeMul O
	 * @param x
	 */
	public void setO(char x)
	{
		O = new OpeMul(x);
	}

	//accesseur
	/**
	 * Accesseur de O
	 */
	public OpeMul getO()
	{
		return O;
	}
	/**
	 * Verifie si le terme est vrai ou faux
	 * @return boolean actif
	 * @see Facteur#isActif()
	 */
	public boolean isActif()
	{
		return actif;
	}

	//Calcul
	/**
	 * Calcul le terme en cours grâce au calcul des facteurs
	 * @see Facteur#Calcul()
	 * @return Netg
	 */
	public Netg Calcul()
	{
		if( f2== null ||O == null)
			return f1.Calcul();
		else if( O.isMul() )
		{
			return NetgMath.multiplication( f1.Calcul() , f2.Calcul() );
		}
		return NetgMath.division( f1.Calcul() , f2.Calcul() );
	}

}
